package protocol.common.httpclient.handler;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.protocol.HttpContext;


/**
 * HttpClient 工具类
 * 默认的请求处理实现类
 * 实现固定时间内，如果出现访问异常，将根据配置重新请求
 *
 * @author 陈杰
 * @version 1.0
 * @since 2016年3月3日 00:18:48
 *
 * Copyright (c) 2016 陈杰(chenjie_java@aliyun.com)
 */
public class HttpRequestDefaultHandler implements HttpRequestRetryHandler{

	private int maxActionCount = 3;
	
	private int sleepTime = 30 * 1000;
	
	/**
	 * 创建默认的请求处理类
	 * 
	 * @param maxActionCount 最大重新连接次数
	 * @param sleepTime      每次重新请求的休眠时间
	 * */
	public static HttpRequestDefaultHandler createDefaultHandler(int maxActionCount,int sleepTime){
		HttpRequestDefaultHandler handler = new HttpRequestDefaultHandler();
		handler.maxActionCount = maxActionCount;
		handler.sleepTime = sleepTime;
		return handler;
	}
	
	/**
	 * 创建默认的请求处理类
	 * */
	public static HttpRequestDefaultHandler createDefaultHandler(){
		return new HttpRequestDefaultHandler();
	}
	
	/**
	 * 处理http请求结果
	 * */
	@SuppressWarnings("static-access")
	@Override
	public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
		if (executionCount >= maxActionCount) {// 如果已经重试了5次，就放弃 
			try {
				Thread.currentThread().sleep(sleepTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
            return false;
        }
        if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接，那么就重试                    
            return true;
        }
        if (exception instanceof InterruptedIOException) {// 超时                    
            return true;
        }
        if (exception instanceof UnknownHostException) {// 目标服务器不可达                    
            return false;
        }
        if (exception instanceof ConnectTimeoutException) {// 连接被拒绝                    
            return false;
        }
        return false;
	}

}
